package order

import (
	"bgs/conf"
	"bgs/grpc/gen/proxy2/inventory"
	"bgs/grpc/imp/enums"
	"bgs/nsqp/topic"
	"bgs/nsqp/util"
	"encoding/json"
	"github.com/nsqio/go-nsq"
	"go.uber.org/zap"
	"time"
)

type enumActionOfOrderNotifyToInventory string

const (
	// actionOfOrderNotifyToInventoryReceived receive incude picked and received
	actionOfOrderNotifyToInventoryReceived enumActionOfOrderNotifyToInventory = "received"

	// actionOfOrderUpdateToInventoryRefundApply 售后申请
	// actionOfOrderUpdateToInventoryRefundApply enumActionOfOrderUpdateToInventory = "refund_apply"

	// actionOfOrderUpdateToInventoryRefundCancel 售后取消
	// actionOfOrderUpdateToInventoryRefundCancel enumActionOfOrderUpdateToInventory = "refund_cancel"
)

// orderUpdateToInventory topicOfOrderUpdateToInventory's body
type orderUpdateToInventory struct {
	OrderNumber string               `json:"order_number"`
	Action      string               `json:"action"`
	Timestamp   int64                `json:"timestamp"`
	Source      inventory.SourceEnum `json:"source"`
}

// func makeProducerTopic(topic string) string {
// 	return fmt.Sprintf("%s-%s", enums.APPIDBGS, topic)
// }

// NsqProducerProxy publish nsq message producer
type NsqOrderRunner struct {
	slog     *zap.SugaredLogger
	producer *nsq.Producer
}

// NewNsqOrderRunner initialization
func NewNsqOrderRunner(
	nsqConf conf.NsqSection,
	slog *zap.SugaredLogger,
) (proxy *NsqOrderRunner, err error) {
	proxy = &NsqOrderRunner{
		slog: slog.With("module", "NsqOrderRunner"),
	}
	config := nsq.NewConfig()

	producer, err := nsq.NewProducer(nsqConf.NsqdAddress, config)
	if err != nil {
		return
	}
	proxy.producer = producer
	nsqLogger := util.NewNoopNSQLogger(slog)
	producer.SetLogger(
		nsqLogger,
		nsq.LogLevelError,
	)

	// Gracefully stop the consumer.
	// consumer.Stop()

	return
}

// PublishOrderPickedParam order picked
type PublishOrderPickedParam struct {
	OrderSerialNumber string
	Picked            time.Time
}

// PublishOrderPicked 发送订单确认自提消息
func (s *NsqOrderRunner) PublishOrderPicked(p PublishOrderPickedParam) (err error) {
	msg := orderUpdateToInventory{
		OrderNumber: p.OrderSerialNumber,
		Action:      string(actionOfOrderNotifyToInventoryReceived),
		Timestamp:   p.Picked.Unix(),
		Source:      inventory.SourceEnum_XT_ORDER,
	}
	body, err := json.Marshal(msg)
	if err != nil {
		return
	}
	err = s.producer.Publish(util.MakeTopic(enums.APPIDINVENTORY)(topic.OrderNotify), body)
	return
}

// PublishOrderReceivedParam order received
type PublishOrderReceivedParam struct {
	OrderSerialNumber string
	Received          time.Time
}

// PublishOrderReceived 发送订单确认收货消息
func (s *NsqOrderRunner) PublishOrderReceived(p PublishOrderReceivedParam) (err error) {
	msg := orderUpdateToInventory{
		OrderNumber: p.OrderSerialNumber,
		Action:      string(actionOfOrderNotifyToInventoryReceived),
		Timestamp:   p.Received.Unix(),
		Source:      inventory.SourceEnum_XT_ORDER,
	}
	body, err := json.Marshal(msg)
	if err != nil {
		return
	}
	err = s.producer.Publish(util.MakeTopic(enums.APPIDINVENTORY)(topic.OrderNotify), body)
	return
}
